package  
{
	import EventDispatchers.XMLLoader;
	
	import Events.XMLEvent;
	
	import Graphics.Animation;
	import Graphics.TileSet;
	
	import Players.Player;
	
	import Utils.*;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class GameObject
	{
		protected var level:Level;
		protected var blitRectangle:Rectangle;
		protected var tileSet:TileSet;
		protected var attack:int = 0;
		
		protected var position:Point = new Point(0,0);
		protected var worldPosition:Point = new Point(0,0);
		protected var startPosition:Point = new Point(0,0);
		
		protected var width:int;
		protected var height:int;
		//is sprite active
		protected var isVisible:Boolean;
		protected var isMoveable:Boolean = true;
		protected var allowCollision:uint = Collision.ANY;
		
		protected var grounded:Boolean = false;
		
		public function GameObject(level:Level)
		{
			this.level = level;
		}
		
		public function Update(deltaTime:int):void
		{
		}
		
		public function set Level(value:Level):void {this.level = value;}
		public function get CurrentLevel():Level {return this.level ;}
		
		
		public function Draw(camera:Camera,canvas:BitmapData):BitmapData
		{
			this.position.x = this.worldPosition.x - camera.X;
			this.position.y = this.worldPosition.y - camera.Y;
			canvas.copyPixels(tileSet.bitmapData, blitRectangle, position);
			return canvas;
		}
		public function Destroy():void
		{
			
		}
		
		public function setPosition(x:int, y:int):void
		{
			startPosition.x = x * level.TileSize;
			startPosition.y = y * level.TileSize;
			worldPosition.x = x * level.TileSize;
			worldPosition.y = y * level.TileSize;
		}
		
		public function setPositionWithPoint(position:Point):void
		{
			startPosition = position;
			//worldPosition = position;
		}
		
		public function collide(object:GameObject, callBack:Function = null):void
		{
			if(checkCollision(object))
			{
				if(callBack === null)
					directionalCollision(object);
				else
					callBack(object);
			}
		}
		
		private function checkCollision(object:GameObject):Boolean
		{			
			if((this.WorldPosition.x <= (object.WorldPosition.x + object.width)) && ((this.WorldPosition.x + this.Width) >= object.WorldPosition.x))
			{
				if((this.WorldPosition.y <= (object.WorldPosition.y + object.Height)) && ((this.WorldPosition.y +this.Height) >= object.WorldPosition.y))
				{
					return true;
				}
				return false;
			}
			return false;
		}
		
		protected function directionalCollision(object:GameObject):void
		{
			var split:Number = 0;
			var top:Number = Math.abs(this.WorldPosition.y - (object.WorldPosition.y + object.Height));
			var bottom:Number = Math.abs((this.WorldPosition.y + this.Height) - object.WorldPosition.y);
			var right:Number = Math.abs((this.WorldPosition.x + this.Width) - object.WorldPosition.x);
			var left:Number = Math.abs(this.WorldPosition.x - (object.WorldPosition.x + object.Width));		
			
			if((top < bottom) && (top < right) && (top < left))
			{
				if(!this.CanMove && object.CanMove)
				{
					object.hitCeiling();
					object.WorldPosition.y = this.WorldPosition.y + object.Height;
				}
				else if(this.CanMove && !object.CanMove)
				{
					this.hitCeiling();
					this.WorldPosition.y = object.WorldPosition.y + this.Height;
				}
				else 
				{
					object.hitCeiling();
					this.hitCeiling();
					split = top / 2;
					object.WorldPosition.y += split;
					this.WorldPosition.y -= split;
				}
			}
			else if((bottom < right) && (bottom < left))
			{
				if(!this.CanMove && object.CanMove)
				{
					object.hitFloor();
					object.WorldPosition.y = this.WorldPosition.y - object.Height;
				}
				else if(this.CanMove && !object.CanMove)
				{
					this.hitFloor();
					this.WorldPosition.y = object.WorldPosition.y - this.Height;	
				}
				else 
				{
					object.hitFloor();
					this.hitFloor();
					split = bottom / 2;
					object.WorldPosition.y -= split;
					this.WorldPosition.y += split;
				}
			}
			else if(right < left)
			{
				if(!this.CanMove && object.CanMove)
				{
					object.hitWall();
					object.WorldPosition.x = this.WorldPosition.x + object.Width;
				}
				else if(this.CanMove && !object.CanMove)
				{
					this.hitWall();
					this.WorldPosition.x = object.WorldPosition.x - this.Width;
				}
				else 
				{
					object.hitWall();
					this.hitWall();
					split = right / 2;
					object.WorldPosition.x += split;
					this.WorldPosition.x -= split;
				}
			}
			else
			{
				if(!this.CanMove && object.CanMove)
				{
					object.hitWall();
					object.WorldPosition.x = this.WorldPosition.x - object.Width;
				}
				else if(this.CanMove && !object.CanMove)
				{
					this.hitWall();
					this.WorldPosition.x = object.WorldPosition.x + object.Width;
				}
				else 
				{
					object.hitWall();
					this.hitWall();
					split = left / 2;
					object.WorldPosition.x -= split;
					this.WorldPosition.x += split;
				}
			}
		}	
		
		public function hitWall():Boolean { return true;}
		public function hitCeiling():Boolean { return true;}
		public function hitFloor():Boolean { grounded=true;return true;}
		public function get Damage():int { return attack;}
		public function get Width():int{return width;}
		public function get Position():Point {return position;}
		public function get WorldPosition():Point {return worldPosition;}
		public function get StartPosition():Point {return startPosition;}
		public function set WorldPosition(value:Point):void {worldPosition = value;}
		public function get Height():int {return height;}
		public function get CanMove():Boolean {return isMoveable;}
	}
}